//-----------------------------------------------------------------------------
//	file: spi_clk.v
//	breif:
//		分频模块，提供计数器半周期信号和满周期信号，DIV_CNT_CYCLE和DIV_CNT_HALF的数值应该
//	减一，例如，16分频的话，DIV_CNT_HALF的值应该为4'd7，DIV_CNT_CYCLE的值应该为4'd15。
//		根据dff信号，每次运行8bit或者16bit，只在working=0的时候更新(DATA_WIDTH-1)。
//		(DATA_WIDTH-1)在非运行的时候更新。
//-----------------------------------------------------------------------------
module spi_clk #(
	parameter	DATA_WIDTH = 16,
	parameter	DIV_CNT_WIDTH = 4,
	parameter	DIV_CNT_HALF = 4'd7,
	parameter	DIV_CNT_CYCLE = 4'd15
)
(
	input		clk,
	input		reset,
	input		cpol,
	input		cpha,
	input		working,
	output	reg	sck,
	output	reg	stop,
	output	reg	shif_en,
	output	reg	samp_en
);

// register
reg		[DIV_CNT_WIDTH-1:0] cnt;
reg		[3:0] cnt_bit;
reg		clk_spi;

// counter div
always @(posedge clk or negedge reset)
	if (reset == 1'b0)
		cnt <= {DIV_CNT_WIDTH{1'b0}};
	else if (stop == 1'b1)
		cnt <= {DIV_CNT_WIDTH{1'b0}};
	else if (cnt == DIV_CNT_CYCLE)
		cnt <= {DIV_CNT_WIDTH{1'b0}};
	else if (working == 1'b1)
		cnt <= cnt + 1'b1;

// counter bit
always @(posedge clk or negedge reset)
	if (reset == 1'b0)
		cnt_bit <= 4'd0;
	else if ((cnt == DIV_CNT_CYCLE) && (cnt_bit == (DATA_WIDTH-1)))
		cnt_bit <= 4'd0;
	else if (cnt == DIV_CNT_CYCLE)
		cnt_bit <= cnt_bit + 1'b1;

// clock spi
always @(posedge clk or negedge reset)
	if (reset == 1'b0)
		clk_spi <= 1'b0;
	else if (cnt == DIV_CNT_HALF)
		clk_spi <= 1'b1;
	else if (cnt == DIV_CNT_CYCLE)
		clk_spi <= 1'b0;

// clock spi real
always @(posedge clk or negedge reset)
	if (reset == 1'b0)
		sck <= 1'b0;
	else if (cpol == 1'b1)
		sck <= ~clk_spi;
	else
		sck <= clk_spi;

// shift
always @(posedge clk or negedge reset)
	if (reset == 1'b0)
		shif_en <= 1'b0;
	else if ((cpha == 1'b0) && (cnt == DIV_CNT_CYCLE))
		shif_en <= 1'b1;
	else if ((cpha == 1'b1) && (cnt == DIV_CNT_HALF) && (|cnt_bit == 1'b1))
		shif_en <= 1'b1;
	else
		shif_en <= 1'b0;

// sample
always @(posedge clk or negedge reset)
	if (reset == 1'b0)
		samp_en <= 1'b0;
	else if ((cpha == 1'b0) && (cnt == DIV_CNT_HALF))
		samp_en <= 1'b1;
	else if ((cpha == 1'b1) && (cnt == DIV_CNT_CYCLE))
		samp_en <= 1'b1;
	else
		samp_en <= 1'b0;

// stop
always @(posedge clk or negedge reset)
	if (reset == 1'b0)
		stop <= 1'b0;
	else if ((cnt == DIV_CNT_CYCLE) && (cnt_bit == (DATA_WIDTH-1)))
		stop <= 1'b1;
	else
		stop <= 1'b0;

endmodule
